package com.opennews.openplatform.websocket

import groovy.transform.CompileStatic
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration
import org.springframework.messaging.simp.config.ChannelRegistration
import org.springframework.messaging.simp.config.MessageBrokerRegistry
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
import org.springframework.web.socket.config.annotation.StompEndpointRegistry
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer

/**
 * IMPORTANT!!!
 * THIS CLASS MUST BE REGISTERED AS A SPRING BEAN NAMED webSocketConfig IN grails-app/conf/spring/resource.groovy FILE.
 *
 *  WebSocketConfig is annotated with @Configuration to indicate that it is a Spring configuration class. It is also annotated
 *  with @EnableWebSocketMessageBroker. As its name suggests, @EnableWebSocketMessageBroker enables WebSocket message handling, backed by a message broker.
 */
@CompileStatic
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Value('${websocket.allowedOriginPatterns}')
    String[] allowedOriginPatterns

    @Value('${websocket.destinationPrefixes}')
    String[] destinationPrefixes

    @Value('${websocket.applicationDestinationPrefixes}')
    String[] applicationDestinationPrefixes

    @Value('${websocket.endpoints}')
    String[] endpoints

    @Value('${websocket.withSockJS}')
    boolean withSockJS

    @Override
    void configureMessageBroker(MessageBrokerRegistry config) {
        // enableSimpleBroker() to enable a simple memory-based message broker to carry the messages back to the
        // client on destinations prefixed with /queue and /topic.
        // That means client needs to subscribe the destination starts with /queue or /topic.
        config.enableSimpleBroker(destinationPrefixes)

        // It designates the /ws prefix for messages that are bound for methods annotated with @MessageMapping.
        // This prefix will be used to define all the message mappings.
        // For example, /ws/hello is the endpoint that a method annotated with @MessageMapping("/hello").
        config.setApplicationDestinationPrefixes(applicationDestinationPrefixes)
    }

    @Override
    void registerStompEndpoints(StompEndpointRegistry registry) {
        // The registerStompEndpoints() method registers the /stomp endpoint for websocket connections.
        // That means client connects to something likes ws://localhost:8080/hello-websocket/stomp.
        // Here localhost:8080/hello-websocket is your service full context and /stomp is configured endpoint.
        //
        // setAllowedOriginPatterns("http://localhost:5173") means only allows connection from this domain. This can secure your connection.
        // setAllowedOriginPatterns("*") means allow all domains.
        def registration = registry.addEndpoint(endpoints)
            .setAllowedOriginPatterns(allowedOriginPatterns)
            // .addInterceptors(new MyHandshakeInterceptor())

        if (withSockJS) {
            registration.withSockJS()
        }
    }

    @Override
    void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new MyChannelInterceptor())
    }
}